
float4x4 World;
float4x4 View;
float4x4 Projection;

texture TextureAtlas;
sampler SamplerAtlas = sampler_state
{
	Texture = (TextureAtlas);

	MinFilter = Point;   
    MagFilter = Point;   
    MipFilter = Point;   
        
    AddressU = Clamp;  
    AddressV = Clamp;

};

struct VertexShaderInput
{
	float4 Position : POSITION0;
	float2 TexCoords : TEXCOORD0;
	byte4 textureId : FOG0;
};

struct VertexShaderOutput
{
	float4 Position : POSITION0;
	float2 TexCoords : TEXCOORD0;
	byte4 textureId : FOG0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input, float4x4 Transformation : BLENDWEIGHT)
{
	VertexShaderOutput output;
	float4 transPos = mul(input.Position, transpose(Transformation));
	float4 worldPos = mul (transPos, World);
	float4 viewPos = mul(worldPos, View);
	output.Position = mul(viewPos, Projection);
	output.TexCoords = input.TexCoords;
	output.textureId = input.textureId;

	return output;
}

float2 CalculateAtlasUV(float2 UV, float4 SourceRectangle)
{
	float2 atlasUV;

	atlasUV.x = UV.x * (SourceRectangle.z / 128);
	atlasUV.x += SourceRectangle.x / 128;
	atlasUV.y = UV.y * (SourceRectangle.w / 128);
	atlasUV.y += SourceRectangle.y / 128;

	return atlasUV;
}


float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
	return tex2D(SamplerAtlas, CalculateAtlasUV(input.TexCoords, float4(input.textureId.x * 16.0f, input.textureId.y * 16.0f, 16.0f, 16.0f)));
}

technique HardwareInstancing
{
    pass Pass1
    {
        VertexShader = compile vs_3_0 VertexShaderFunction();
        PixelShader = compile ps_3_0 PixelShaderFunction();
    }
}